package com.liukunup.util;

import io.minio.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.nio.file.Files;
import java.util.concurrent.TimeUnit;

/**
 * 开源 MinIO
 * @author Liu Kun
 * @date 2020-12-12 23:14:17
 * see https://docs.min.io/docs/java-client-api-reference.html
 */
@Slf4j
public class MinIoUtil {

    private static final String MIN_IO_PROPERTIES = "minio.properties";
    private static final String EP = PropertiesUtil.getString(MIN_IO_PROPERTIES, "storage.minio.endpoint", null);
    private static final String AK = PropertiesUtil.getString(MIN_IO_PROPERTIES, "storage.minio.accessKey", null);
    private static final String SK = PropertiesUtil.getString(MIN_IO_PROPERTIES, "storage.minio.secretKey", null);

    private MinioClient minioClient;
    private static MinIoUtil mInstance;

    private MinIoUtil() {
        // 创建客户端
        minioClient = MinioClient.builder().endpoint(EP).credentials(AK, SK).build();
    }

    /**
     * 单例模式
     * 创建 MinIoUtil
     * @return mInstance
     */
    public static MinIoUtil getInstance() {
        if (mInstance == null) {
            synchronized (MinIoUtil.class) {
                mInstance = new MinIoUtil();
            }
        }
        return mInstance;
    }

    public static String upload(String bucketName, String objectName, String filename) {
        String url = null;
        try {
            // 获取客户端
            MinioClient minioClient = getInstance().minioClient;
            // 检查桶是否存储 不存在则创建桶
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if(!isExist) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
            // 获取文件类型
            String contentType = Files.probeContentType(new File(filename).toPath());
            // 上传文件对象
            minioClient.uploadObject(UploadObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .filename(filename)
                    .contentType(contentType)
                    .build());
            // 获取远端文件对象的链接
            url = minioClient.getObjectUrl(bucketName, objectName);
        } catch (Exception ignored) {
        }
        return url;
    }

    public static void download(String bucketName, String objectName, String filename) {
        try {
            // 获取客户端
            MinioClient minioClient = getInstance().minioClient;
            // 下载文件对象
            minioClient.downloadObject(DownloadObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .filename(filename)
                    .build());
        } catch (Exception ignored) {
        }
    }

    public static String getObjectUrl(String bucketName, String objectName) {
        String url = null;
        try {
            // 获取客户端
            MinioClient minioClient = getInstance().minioClient;
            // 获取远端文件对象的链接
            url = minioClient.getObjectUrl(bucketName, objectName);
        } catch (Exception ignored) {
        }
        return url;
    }

    public static String getObjectUrl(String bucketName, String objectName, int expiry, TimeUnit unit) {
        String url = null;
        try {
            // 获取客户端
            MinioClient minioClient = getInstance().minioClient;
            // 获取远端文件对象的链接 此处会设置过期时间
            url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(bucketName)
                    .object(objectName)
                    .expiry(expiry, unit)
                    .build());
        } catch (Exception ignored) {
        }
        return url;
    }

    public static boolean removeObject(String bucketName, String objectName) {
        try {
            // 获取客户端
            MinioClient minioClient = getInstance().minioClient;
            // 删除文件对象
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .build());
        } catch (Exception ignored) {
            return false;
        }
        return true;
    }
}
